package com.hzeport.bgs22emduty.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hzeport.bgs22emduty.dto.BasePersonInfoLSDTO;
import com.hzeport.bgs22emduty.dto.BasePersonInfoLSVO;
import com.hzeport.bgs22emduty.dto.PersonInfoDTO;
import com.hzeport.bgs22emduty.entity.BasePersonInfo;
import com.hzeport.bgs22emduty.entity.SignKey;
import com.hzeport.bgs22emduty.outbound.BasePersonInfoRepository;
import com.hzeport.bgs22emduty.outbound.SignKeyRepository;
import com.hzeport.bgs22emduty.outbound.db.BasePersonInfoRepositoryImpl;
import com.hzeport.bgs22emduty.service.BasePersonInfoService;
import com.hzeport.bgs22emduty.vo.base.PersonInfoData;
import com.hzeport.bgs22emduty.vo.base.PersonInfoVO;
import com.hzeport.bgs22emduty.common.base.BaseResult;
import com.hzeport.bgs22emduty.common.base.BaseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * ${comments}
 *
 * @author code generator
 * @date 2022-12-02 11:21:59
 */
@Service
@Slf4j
public class BasePersonInfoServiceImpl extends BaseServiceImpl<BasePersonInfoRepositoryImpl, BasePersonInfo> implements BasePersonInfoService {

    @Resource
    private BasePersonInfoRepository basePersonInfoRepository;
    @Resource
    private SignKeyRepository signKeyRepository;

    @Override
    public PersonInfoVO<List<PersonInfoData>> getPersonInfo(PersonInfoDTO dto) {
        PersonInfoVO<List<PersonInfoData>> personInfoVO = new PersonInfoVO<>();

        SignKey signKey = signKeyRepository.getOne(new LambdaQueryWrapper<SignKey>()
                .eq(SignKey::getAppKey, dto.getAppKey()));

        if (signKey!=null){
            try {
                String signature = calculatesSHA256(dto.getAppKey() + signKey.getAppSecret() + dto.getTimestamp());
                if (!signature.equals(dto.getSignature())) {
                    personInfoVO.setCode("1");
                    personInfoVO.setMessage("验签失败");
                } else if (!isTimestampToday(dto.getTimestamp())) {
                    personInfoVO.setCode("1");
                    personInfoVO.setMessage("时间戳验证失败");
                } else {
                    Page<PersonInfoData> personInfoPage = basePersonInfoRepository.getPersonInfo(dto);
                    personInfoVO.setData(personInfoPage.getRecords());
                    personInfoVO.setTotal(personInfoPage.getRecords().size());
                    personInfoVO.setCode("0");
                    personInfoVO.setMessage("获取成功");
                }
            } catch (NoSuchAlgorithmException e) {
                personInfoVO.setCode("1");
                personInfoVO.setMessage("验签异常");
                e.printStackTrace();
            }
        }else {
            personInfoVO.setCode("1");
            personInfoVO.setMessage("不存在的key");
        }

        return personInfoVO;
    }

    private String calculatesSHA256(String input) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] hashBytes = md.digest(input.getBytes());

        StringBuilder sb = new StringBuilder();
        for (byte hashByte : hashBytes) {
            sb.append(Integer.toString((hashByte & 0xff) + 0x100, 16).substring(1));
        }

        return sb.toString();
    }

    private boolean isTimestampToday(String timestamp) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        LocalDate localDate = LocalDate.parse(timestamp, formatter);

        LocalDate today = LocalDate.now();

        return localDate.equals(today);

    }

    @Override
    public BaseResult<Page<BasePersonInfoLSVO>> getPage(BasePersonInfoLSDTO dto) {
        if (StringUtils.isBlank(dto.getCustomId())){
            return BaseResult.failed("customId为必传参数");
        }
        if (dto.getPageNum()==null){
            return BaseResult.failed("pageNum为必传参数");
        }
        if (dto.getPageSize()==null){
            return BaseResult.failed("pageSize为必传参数");
        }

        Page<BasePersonInfo> page=new Page<>(dto.getPageNum(),dto.getPageSize());
        Page<BasePersonInfo> personInfoPage = basePersonInfoRepository.page(page, new LambdaQueryWrapper<BasePersonInfo>()
                .eq(BasePersonInfo::getCustomId, dto.getCustomId())
                .like(StringUtils.isNoneBlank(dto.getUserno()), BasePersonInfo::getUserno, dto.getUserno())
                .like(StringUtils.isNoneBlank(dto.getUsername()), BasePersonInfo::getUsername, dto.getUsername()));

        Page<BasePersonInfoLSVO> basePersonInfoLSVOPage=new Page<>();
        BeanUtils.copyProperties(personInfoPage,basePersonInfoLSVOPage);
        List<BasePersonInfoLSVO> basePersonInfoLSVOList=new ArrayList<>();
        for (BasePersonInfo record : personInfoPage.getRecords()) {
            BasePersonInfoLSVO basePersonInfoLSVO=new BasePersonInfoLSVO();
            BeanUtils.copyProperties(record,basePersonInfoLSVO);
            basePersonInfoLSVOList.add(basePersonInfoLSVO);
        }
        basePersonInfoLSVOPage.setRecords(basePersonInfoLSVOList);
        return BaseResult.ok(basePersonInfoLSVOPage);
    }
}
